Git サブモジュールの作成
目標: A プロジェクト内に B プロジェクトを作成し、B プロジェクトを独立したリポジトリとして、git submodule の方法で A プロジェクトに導入する。
一、なぜサブモジュール(submodule)を使用するのか
git submodule を使用する核心的な理由は:
- B プロジェクトは独立して開発・リリースできる
- A プロジェクトは B の特定のバージョンのみを参照する
- 複数のプロジェクトが同じ B を再利用できる
- すべてのコードを 1 つのリポジトリに詰め込むことを避ける(疑似 monorepo)
適切なシーン:
- SDK / ユーティリティライブラリ
- 基本コンポーネント
- 独立した CI / リリースが必要なモジュール
二、全体的なプロセス概要
- A プロジェクト内に B プロジェクトディレクトリを作成
- B プロジェクトを独立した Git リポジトリとして初期化
ghを使用してリモートリポジトリを作成しプッシュ- B プロジェクトを submodule として A プロジェクトに追加
- A プロジェクトの submodule 変更をコミット
三、A プロジェクト内に B プロジェクトを作成
A プロジェクトのルートディレクトリに移動:
cd A-project
B プロジェクトディレクトリを作成(例):
mkdir -p packages/B-project
cd packages/B-project
四、B プロジェクトリポジトリの初期化
1. Git を初期化
git init
2. 初期コミットを作成(必須)
echo "# B-project" > README.md
git add .
git commit -m "chore: initial commit"
⚠️ submodule はコミットのないリポジトリを参照できません
五、GitHub CLI を使用してリモートリポジトリを作成
GitHub にログインしていることを確認:
gh auth status
リポジトリを作成してプッシュ(fish / bash 共通の書き方):
gh repo create B-project --private --source=. --remote=origin --push
パブリックリポジトリの場合は、
--privateを--publicに変更してください
リモートリポジトリを確認:
git remote -v
六、B プロジェクトをサブモジュールとして A プロジェクトに追加
1. A プロジェクトのルートディレクトリに戻る
cd ../../
2. ローカルの B ディレクトリを削除(重要なステップ)
rm -rf packages/B-project
⚠️ submodule は自動的にリポジトリをクローンするため、ローカルディレクトリは空である必要があります
3. submodule を追加
git submodule add https://github.com/<ユーザー名または組織>/B-project.git packages/B-project
成功後、以下が生成されます:
packages/B-project/.gitmodules
七、A プロジェクトの submodule 変更をコミット
git add .gitmodules packages/B-project
git commit -m "chore: add B-project as submodule"
git push
八、日常の開発と更新プロセス
1. B プロジェクトを開発
cd packages/B-project
git checkout main
変更してコミット:
git add .
git commit -m "feat: xxx"
git push
2. A プロジェクト内でサブモジュールバージョンを更新
cd ../../
git status
以下のように表示されます:
modified: packages/B-project (new commits)
更新をコミット:
git add packages/B-project
git commit -m "chore: bump B-project submodule"
git push
九、submodule を含むプロジェクトをクローン
推奨方法(一度に)
git clone --recurse-submodules <A-project-repo>
既にクローンしたプロジェクトにサブモジュールを追加
git submodule update --init --recursive
十、よくある落とし穴のまとめ
❌ B プロジェクトの初期コミットを忘れた
→ submodule を追加できません
❌ ローカルディレクトリを削除せずに submodule を追加
→ already exists and is not a git repository
❌ B を更新したが、A の submodule ポインタをコミットしなかった
→ 他の人は最新バージョンを取得できません
十一、補足の提案
- サブモジュールを
packages/またはlibs/ディレクトリに統一 - submodule の更新は個別のコミットが必須
- チーム内で約束:submodule の detached HEAD を直接変更することを禁止
結論: submodule が管理するのは「依存関係のコミット」であり、コード自体ではありません。 「誰がリリースを担当し、誰が参照するのか」を明確にすれば、落とし穴を避けられます。
ご希望であれば、このノートを以下の形式に変更することもできます:
- チーム規範版
- README 簡潔版
- フローチャート付きバージョン